package controller

import (
	"go-data-spider/server/model"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/labstack/echo/v4"
)

// SimulateForm 模拟交易表单（仅支持JSON请求）
type SimulateForm struct {
	Code          string  `json:"code" validate:"required"`
	InitCash      float64 `json:"initCash" validate:"required,gt=0"`
	MADays        int     `json:"maDays" validate:"required,gt=0"`
	SellRatio     float64 `json:"sellRatio" validate:"required,gt=0"`
	BuyRatio      float64 `json:"buyRatio" validate:"required,gt=0"`
	ServiceCharge float64 `json:"serviceCharge" validate:"required,gte=0"`
	DateBegin     *string `json:"dateBegin"`
	DateEnd       *string `json:"dateEnd"`
}

// Simulate 执行交易策略模拟
func Simulate(c echo.Context) error {
	// 创建请求结构体实例
	var form SimulateForm

	// 使用 c.Bind() 解析 JSON 请求（自动处理 Content-Type）
	if err := c.Bind(&form); err != nil {
		// 自定义错误信息，提供更友好的提示
		return echo.NewHTTPError(http.StatusBadRequest, map[string]interface{}{
			"error":   "请求格式错误",
			"details": err.Error(),
			"hint":    "请确保发送 JSON 格式数据，并且数值类型参数使用数字（如 initCash: 10000.0 而非 \"10000.0\"）",
		})
	}

	// 获取指数数据
	code := strings.TrimSpace(form.Code)
	indexDataList, err := model.ListIndexDataByCode(code)
	if err != nil {
		return echo.NewHTTPError(http.StatusInternalServerError, "获取指数数据失败: "+err.Error())
	}

	// 按日期过滤数据
	dateBegin := ""
	if form.DateBegin != nil {
		dateBegin = *form.DateBegin
	}
	dateEnd := ""
	if form.DateEnd != nil {
		dateEnd = *form.DateEnd
	}
	indexDataList = FilterIndexDataByDateRange(indexDataList, dateBegin, dateEnd)

	// 执行模拟
	simulateResult := model.Simulate(
		form.InitCash,
		form.MADays,
		form.SellRatio,
		form.BuyRatio,
		form.ServiceCharge,
		indexDataList,
	)

	// 直接返回模拟结果，移除code和data包装
	return c.JSON(http.StatusOK, simulateResult)
}

// FilterIndexDataByDateRange 按日期范围过滤指数数据
func FilterIndexDataByDateRange(
	indexDataList []model.IndexData,
	dateBegin, dateEnd string,
) []model.IndexData {
	// 解析日期
	var beginDate, endDate *time.Time

	if dateBegin != "" {
		parsedDate, err := time.Parse("2006-01-02", dateBegin)
		if err != nil {
			log.Println("日期格式错误: ", err.Error())
			return []model.IndexData{}
		}
		beginDate = &parsedDate
		log.Println("beginDate: ", *beginDate)
	}

	if dateEnd != "" {
		endDate, err := time.Parse("2006-01-02", dateEnd)
		log.Println("endDate: ", endDate)
		if err != nil {
			log.Println("日期格式错误: ", err.Error())
			return []model.IndexData{}
		}
	}

	// 过滤数据
	var filteredData []model.IndexData
	for _, item := range indexDataList {
		itemDate, err := time.Parse("2006-01-02", item.Date)
		if err != nil {
			continue
		}

		// 检查日期范围
		include := true
		if beginDate != nil && itemDate.Before(*beginDate) {
			include = false
		}
		if endDate != nil && itemDate.After(*endDate) {
			include = false
		}

		if include {
			filteredData = append(filteredData, item)
		}
	}

	return filteredData
}
